The NAT checksum fixes in patches/linux-2.6.16-rc2/net-csum.patch do
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 8 Feb 2006 23:22:38 +0000 (00:22 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 8 Feb 2006 23:22:38 +0000 (00:22 +0100)
not work when port numbers are modified (bug 447).
tcp_manip_pkt()/udp_manip_pkt() modify the protocol checksum to
reflect the changes to ip addresses and port numbers.  When
dev_queue_xmit() finds a message with proto_csum_blank set, it
calculates a new tcp/udp checksum that includes both the modified port
numbers and the modified protocol checksum field...  so the change to
the port numbers affects the protocol checksum twice.

This patch modifies net-csum.patch to remove the checksum mangling for
port numbers in tcp_manip_pkt()/udp_manip_pkt()

Signed-off-by: Jim Dykman <dykman@us.ibm.com>
patches/linux-2.6.16-rc2/net-csum.patch

index a1b4a24c0c118fc57c1a0f99f8fefbcd71c32c2e..4d7ede087428404365dc49ea9f383121d7703b43 100644 (file)
@@ -1,16 +1,14 @@
 diff -pruN ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c
 --- ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp.c    2006-02-02 17:39:51.000000000 +0000
 +++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c    2006-02-02 17:44:18.000000000 +0000
-@@ -129,10 +129,16 @@ tcp_manip_pkt(struct sk_buff **pskb,
+@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
        if (hdrsize < sizeof(*hdr))
                return 1;
  
 -      hdr->check = ip_nat_cheat_check(~oldip, newip,
 +      if ((*pskb)->proto_csum_blank) {
-+              hdr->check = ip_nat_cheat_check(oldip, ~newip,
-+                              ip_nat_cheat_check(oldport ^ 0xFFFF,
-+                                      newport, hdr->check));
-+      } else { 
++              hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
++      } else {
 +              hdr->check = ip_nat_cheat_check(~oldip, newip,
                                        ip_nat_cheat_check(oldport ^ 0xFFFF,
                                                           newport,
@@ -18,22 +16,19 @@ diff -pruN ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp
 +      }
        return 1;
  }
+
 diff -pruN ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c
 --- ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_udp.c    2006-02-02 17:39:51.000000000 +0000
 +++ ./net/ipv4/netfilter/ip_nat_proto_udp.c    2006-02-02 17:44:18.000000000 +0000
-@@ -113,11 +113,19 @@ udp_manip_pkt(struct sk_buff **pskb,
+@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb,
                newport = tuple->dst.u.udp.port;
                portptr = &hdr->dest;
        }
 -      if (hdr->check) /* 0 is a special case meaning no checksum */
 -              hdr->check = ip_nat_cheat_check(~oldip, newip,
-+      
 +      if (hdr->check) { /* 0 is a special case meaning no checksum */
 +              if ((*pskb)->proto_csum_blank) {
-+                      hdr->check = ip_nat_cheat_check(oldip, ~newip, 
-+                                      ip_nat_cheat_check(*portptr ^ 0xFFFF, 
-+                                              newport, hdr->check));
++                      hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
 +              } else {
 +                      hdr->check = ip_nat_cheat_check(~oldip, newip,
                                        ip_nat_cheat_check(*portptr ^ 0xFFFF,